mysql 主从

mysql主从基本原理

  一个主库,可以读写,一个从库可读,不可写。
  流程:一个更新操作:
  1.主库执行更新操作,写入到binlog里面。,备库和主库维持一个长连接。主库内部有个线程,专门用于服务备库的这个长连接。
2.备库通过change master 设置主库A的ip,端口,用户名,密码,以及要从哪个位置来请求binlog,这个位置包含文件名和日志偏移量。
  3.备库执行start slave 命令,这个时候,备库会启动2个线程。一个叫做 io_thread(用来负责和主库建立连接),主库检验完用户名。密码后开始按照备库传过来的位置读取binlog,发送给备库,备库拿到数据后,放到relay log。另一个线程就是sql_thread ,读取relay log.然后执行。
  双主结构:从节点和主节点互为主备关系。切换时不修改主备关系。但是从节点依旧是readonly.互为主备存在循环日志关系,比如a把binlog发给了b,b接受到后吧日志发给了a,如此就循环了,这边方法时每个库的serverid保持不一样,当接受日志的时候,当发现serverid和自己一样时,丢掉日志。

binlog3个格式

  statement:记录原语句。
  row:记录的是修改后的动作。比如删除 id=1,新增 id2=2等信息。直接记录的就是数据.
  mix:混合上面2个格式的。为何有这种格式呢?statement,直接执行语句可能导致报错,而row占的空间太大。使用mix,不存在歧义的语句采用statement,存在歧义的使用row。
  歧义sql:
   delete from t where a>=4 and t_modified<=’2018-11-10’ limit 1;
  其可能使用a这个索引,或者t_modified这个索引。采用不同索引,可能删除的数据不一样。
  row格式日志其保存了修改前后的变化,如果误操作了,可以查看回滚。所以一般都是用这个row这种格式来记录binlog。如果用statement格式的binlog恢复数据时,要先用mysqlbinlog解析出来,再把结果发给mysql执行。

主备延迟

  每个事务都有一个时间,这个时间就是主库写入时间,而主备延迟是从库写入的系统时间,减去这个主库写入时间的差值。这个时间值一般来源于,从库接受到数据,到写入到从库的时间。网络影响较小。
  原因如下:
  1.由于备库没有请求,于是给备库配置的机器极差,但是,备库同步数据时,对磁盘的操作也是有的,更新操作也很多,因此,造成了大量的延迟。
  2.让备库去处理请求,由于考虑到只是读请求,因此不加限制,导致备库同步数据慢。
   针对原因2解决方案:
   1:增加几个从库
   2.将信息binlog输出到外部系统Hadoop来减轻压力。
   3.大事务,一个大的事务,在主库都执行了很久,何况从库。
   4.DDL,ddl会重建表。而大表的重建,性能损耗很大。
  3.备库的并行复制能力

双主切换流程

  1.判断延迟时间是否小于一个阈值。否则重复这一步。
  2.将主库改为只读,
  3.判断备库的延迟时间是否为0.
  4.将备库改为可读写。
  5,将请求切换到备库B.
  其中最耗时的是步骤3,因此我们要控制好步骤一的阈值,从而减少不可用时间。 按照这个步骤可以让可靠性达到最高。,但是可用性会随之下降。假设先执行4.5步骤,可用性最高,一直可用,主库插入一个数据4,主键自增,(1,4)。然后切换主备,这个(1,4)没有写入到从库,然后新增数据5,从库存了(1,5)然后,接受到存4,存了(2,4)然后主从数据库不一致了。   如果是row格式的binlog,那就不是数据不一致,那是数据根本存不进去。
  如果发生异常,主库宕机了,而从库延迟时间极长,那么切换为从库,会造成系统长时间不可用。因此mysql高可用是建立在延迟时间短的情况下的。